#ifndef SMOOTHER_H
#define SMOOTHER_H

#include "mtxlib.h"
#include <vector>

using namespace std;

#define RING	30	
#define TOLERATE	1e-3

class Triangle;
class Vertex;

typedef vector<Triangle*> TriangleList;
typedef vector<Vertex*> VertexList;
typedef vector<int> IndexList;

class Vertex
{
public:
	Vertex();
	~Vertex();

	vector3 position;
	vector3 normal;
	int index;
	TriangleList neighbour;
};

class Triangle
{
public:
	Triangle();
	~Triangle();
	

	int v1;
	int v2;
	int v3;
};

class Smoother
{
public:
	virtual ~Smoother(void){};
	virtual void SmootingIter()=0;
	virtual void InitLaplacian()=0;
	void ApplySmoothing(int iter);
	vector3 getNormal(Triangle* tri, int v);
	IndexList getNeighbours(int v);
	void DataFlip();

	TriangleList triangles;
	VertexList* vertices;
	VertexList* newVertices;
};

class ExplicitSmoother	: public virtual Smoother
{
public:
	ExplicitSmoother(float lambda, float timeStep);
	~ExplicitSmoother(void);
	void SmootingIter();
	void InitLaplacian(){};	
	

	float lambda;
	float dt;
};

class ImplicitSmoother	: public virtual Smoother
{
public:
	ImplicitSmoother(float lambda, float timeStep);
	~ImplicitSmoother(void);
	void SmootingIter();
	void InitLaplacian();
	void InitSystem();
	void SparseSolver();
	void JacobiIter();
	void UpdateSolution();


	float **A;
	float *b;
	float *buffer;
	float *x;
	int **index;
	float **Laplacian;
	float lambda;
	float dt;
};

#endif

